home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 401-425 / disk_408 / post / post13.lzh / Post / source / postband.c < prev    next >
C/C++ Source or Header  |  1990-10-27  |  21KB  |  814 lines

  1. /* Band rendering print driver for Post V1.3.  File "postband.c"
  2.  * (C) Adrian Aylward 1989, 1990
  3.  *
  4.  * You may freely copy, use, and modify this file.
  5.  *
  6.  * This file is a PostScript program driver that splits a PostScript file
  7.  * that conforms to the structuring conventions and calls Post to print
  8.  * it in a series of bands, even if there is not enough memory for a full
  9.  * page buffer.  It is totally Amiga specific.
  10.  *
  11.  * The program was tested using Lattice C V5.05.  It has various Lattice
  12.  * dependencies.
  13.  */
  14.  
  15. # include <dos.h>
  16. # include <devices/printer.h>
  17. # include <devices/prtbase.h>
  18. # include <exec/exec.h>
  19. # include <exec/execbase.h>
  20. # include <exec/tasks.h>
  21. # include <graphics/gfx.h>
  22. # include <graphics/rastport.h>
  23. # include <proto/dos.h>
  24. # include <proto/exec.h>
  25. # include <stdio.h>
  26. # include <string.h>
  27.  
  28. # include "postlib.h"
  29.  
  30. /* Assembler routines */
  31.  
  32. extern void insertbreak(void);
  33. extern void deletebreak(void);
  34. extern void insertftrap(void);
  35. extern void deleteftrap(void);
  36.  
  37. /* Routines defined and referenced only within this module */
  38.  
  39. extern void prints(BPTR fh, char *string);
  40. extern void errmsg(char *string);
  41. extern void setprinter(void);
  42. extern void setprintden(void);
  43. extern int  strtoint(char **sp, int *ip);
  44. extern void __saveds __asm copypage(register __d0 int num);
  45. extern void printpage(void);
  46. extern void splitpage(void);
  47.  
  48. /* External data (initialised to zero) */
  49.  
  50. int retcode, errcode, ioerror;
  51.  
  52. int arec;
  53.  
  54. BPTR errfh;
  55.  
  56. int ybase;
  57. int prologue, trailer;
  58. FILE *printfile;
  59.  
  60. struct library *PSbase;
  61. struct PSparm parm;
  62.  
  63. struct BitMap bitmap;
  64. struct ColorMap colormap;
  65.  
  66. int propen, prden;
  67. struct IODRPReq prreq;
  68. struct PrinterData *prdata;
  69. struct PrinterExtendedData *prextdata;
  70. struct Preferences *prprefs;
  71. struct RastPort prrast;
  72. struct MsgPort *prport;
  73. ULONG prsig;
  74. UBYTE prstatus[2];
  75.  
  76. int breakset, ftrapset;
  77.  
  78. /* Colour tables.  The default color map type is a vector or UWORD RGB
  79.  * values.  The colours are inverted as we set a bit in the bitmap whenever
  80.  * we want to place a drop of (black or cyan/magenta/yellow) ink */
  81.  
  82. static UWORD bcolors[2] =  /* Black and white */
  83. {   0xfff, 0x000                /* White   black */
  84. };
  85.  
  86. static UWORD ccolors[16] = /* Colour (RGB or CMYK) */
  87. {   0xfff, 0x0ff, 0xf0f, 0x00f, /* White   cyan    magenta blue */
  88.     0xff0, 0x0f0, 0xf00, 0x000, /* Yellow  green   red     black */
  89.     0x000, 0x000, 0x000, 0x000, /* Black */
  90.     0x000, 0x000, 0x000, 0x000  /* Black */
  91. };
  92.  
  93. /* Arguments */
  94.  
  95. int argfilec, argsizec, argmemc;
  96. char *argprint;
  97. char *argfilev[5], *argsizev[5], *argmemv[5];
  98. char *argkey[] =
  99. {   "PRINT", "SIZE", "MEM", NULL };
  100.  
  101. /* Startup code */
  102.  
  103. extern void main(int argc, char **argv);
  104.  
  105. void _main(char *line)
  106. {   char *argv[32];
  107.     int argc;
  108.  
  109.     /* Parse the arguments to break words and strip quotes.  N.B. the
  110.      * main program can determine that the arument was quoted by inspecting
  111.      * the preceeding character */
  112.  
  113.     argc = 0;
  114.     if (line == NULL) goto endline;
  115.     for (;;)
  116.     {   while (*line == ' ' || *line == '\t' || *line == '\n') line++;
  117.         if (*line == 0) break;
  118.         if (argc == 32)
  119.         {   argc = 0;
  120.             goto endline;
  121.         }
  122.         if (*line == '"')
  123.         {   argv[argc] = ++line;
  124.             while (*line != '"')
  125.             {   if (*line == 0)
  126.                 {   argc = 0;
  127.                     goto endline;
  128.                 }
  129.                 line++;
  130.             }
  131.         }
  132.         else
  133.         {   argv[argc] = line;
  134.             while (*line != ' ' && *line != '\t' && *line != '\n')
  135.             {   if (*line == 0)
  136.                 {   argc++;
  137.                     goto endline;
  138.                 }
  139.                 line++;
  140.             }
  141.         }
  142.         *line++ = 0;
  143.         argc++;
  144.     }
  145. endline:
  146.  
  147.     /* Set up the standard input/output files */
  148.  
  149.     errfh = Open("*", MODE_OLDFILE);
  150.     if (errfh == NULL)
  151.     {   retcode = 20;
  152.         goto tidyexit;
  153.     }
  154.  
  155.     /* Call the main program  */
  156.  
  157.     main(argc, argv);
  158.  
  159.     /* Tidy up and exit */
  160.  
  161. tidyexit:
  162.     if (errfh) Close(errfh);
  163.  
  164.     XCEXIT(retcode);
  165. }
  166.  
  167. /* Main program */
  168.  
  169. void main(int argc, char **argv)
  170. {   char *s;
  171.     int *ip, i, ch;
  172.     int xsize, ysize, ssize, xoff, yoff, xden, yden, pden;
  173.  
  174.     /* Open the libraries */
  175.  
  176.     PSbase = OpenLibrary("post.library", 0);
  177.     if (PSbase == NULL)
  178.     {   errmsg("can't open post.library");
  179.         goto errorexit;
  180.     }
  181.  
  182.     /* Parse the arguments and keywords.  See the usage string below */
  183.  
  184.     argc--;
  185.     argv++;
  186.     if (argc == 0 || (argc == 1 && strcmp(*argv, "?") == 0)) goto usage;
  187.  
  188.     while (argc--)
  189.     {   s = *argv++;
  190.         i = -1;
  191.         if (s[-1] != '"')
  192.             for (;;)
  193.             {   i++;
  194.                 if (argkey[i] == NULL)
  195.                 {   i = -1;
  196.                     break;
  197.                 }
  198.                 if (stricmp(s, argkey[i]) == 0) break;
  199.             }
  200.         switch (i)
  201.         {   case  0:    /* PRINT */
  202.                 if (argc == 0) goto badargs;
  203.                 argc--;
  204.                 argprint = *argv++;
  205.                 break;
  206.  
  207.             case  1:    /* SIZE */
  208.                 if (argc == 0) goto badargs;
  209.                 argc--;
  210.                 if (argsizec == 5) goto badargs;
  211.                 argsizev[argsizec++] = *argv++;
  212.                 break;
  213.  
  214.             case  2:    /* MEM */
  215.                 if (argc == 0) goto badargs;
  216.                 argc--;
  217.                 if (argmemc == 5) goto badargs;
  218.                 argmemv[argmemc++] = *argv++;
  219.                 break;
  220.  
  221.             default:
  222.                 if (argfilec == 5) goto badargs;
  223.                 argfilev[argfilec++] = s;
  224.         }
  225.     }
  226.     if (argprint == NULL) goto badargs;
  227.  
  228.     /* Get up the default page size from the printer preferences */
  229.  
  230.     bitmap.BytesPerRow = 1;
  231.     bitmap.Rows = 1;
  232.     bitmap.Flags = 0;
  233.     bitmap.Depth = parm.page.depth = 3;
  234.     setprinter();
  235.     parm.page.xoff = 0;
  236.     parm.page.yoff = 0;
  237.     if (prport == NULL)
  238.     {   errmsg("can't open printer device");
  239.         goto errorexit;
  240.     }
  241.     parm.page.ydir = -1;
  242.  
  243.     /* Parse the "SIZE xyod..s..p.bc." options */
  244.  
  245.     xsize = ysize = ssize = xden = yden = pden = 0;
  246.     for (i = 0; i < argsizec; i++)
  247.     {   s = argsizev[i];
  248.         for (;;)
  249.         {   ch = *s++;
  250.             if (ch == 0) break;
  251.             ch = tolower(ch);
  252.             switch (ch)
  253.             {   case 'x':
  254.                     if      (tolower(*s) == 'o')
  255.                     {   s++;
  256.                         if (!strtoint(&s, &xoff)) goto badvalue;
  257.                         parm.page.xoff = xoff;
  258.                         continue;
  259.                     }
  260.                     else if (tolower(*s) == 'd')
  261.                     {   s++;
  262.                         ip = &xden;
  263.                     }
  264.                     else
  265.                         ip = &xsize;
  266.                     break;
  267.  
  268.                 case 'y':
  269.                     if      (tolower(*s) == 'o')
  270.                     {   s++;
  271.                         if (!strtoint(&s, &yoff)) goto badvalue;
  272.                         parm.page.yoff = yoff;
  273.                         continue;
  274.                     }
  275.                     else if (tolower(*s) == 'd')
  276.                     {   s++;
  277.                         ip = &yden;
  278.                     }
  279.                     else
  280.                         ip = &ysize;
  281.                     break;
  282.  
  283.                 case 's':
  284.                     ip = &ssize;
  285.                     break;
  286.  
  287.                 case 'p':
  288.                     ip = &pden;
  289.                     break;
  290.  
  291.                 case 'd':
  292.                 {   if (!strtoint(&s, &xden)) goto badvalue;
  293.                     yden = xden;
  294.                     continue;
  295.                 }
  296.  
  297.                 case 'b':
  298.                     parm.page.depth = 1;
  299.                     continue;
  300.  
  301.                 case 'c':
  302.                     ch = *s;
  303.                     if      (ch == '3')
  304.                     {   s++;
  305.                         parm.page.depth = 3;
  306.                     }
  307.                     else if (ch == '4')
  308.                     {   s++;
  309.                         parm.page.depth  = 4;
  310.                     }
  311.                     else
  312.                         parm.page.depth = 3;
  313.                     continue;
  314.  
  315.                 default:
  316.                     goto badvalue;
  317.             }
  318.             if (!strtoint(&s, ip)) goto badvalue;
  319.         }
  320.     }
  321.     if (xden != 0) parm.page.xden = xden;
  322.     if (yden != 0) parm.page.yden = yden;
  323.     if (xsize != 0) parm.page.xsize = xsize;
  324.     if (ysize != 0) parm.page.ysize = ysize;
  325.     if (pden != 0)
  326.     {   prden = pden;
  327.         setprintden();
  328.     }
  329.  
  330.     /* Set up the default memory sizes */
  331.  
  332.     parm.memvlen = 280000;
  333.     parm.memflen =  60000;
  334.     parm.memllen =  60000;
  335.     parm.memhlen =  20000;
  336.  
  337.     /* Parse the "MEM fhlv.." options */
  338.  
  339.     for (i = 0; i < argmemc; i++)
  340.     {   s = argmemv[i];
  341.         for (;;)
  342.         {   ch = *s++;
  343.             if (ch == 0) break;
  344.             ch = tolower(ch);
  345.             switch (ch)
  346.             {   case 'f':
  347.                     ip = &parm.memflen;
  348.                     break;
  349.  
  350.                 case 'h':
  351.                     ip = &parm.memhlen;
  352.                     break;
  353.  
  354.                 case 'l':
  355.                     ip = &parm.memllen;
  356.                     break;
  357.  
  358.                 case 'v':
  359.                     ip = &parm.memvlen;
  360.                     break;
  361.  
  362.                 default:
  363.                     goto badvalue;
  364.             }
  365.             if (!strtoint(&s, ip)) goto badvalue;
  366.         }
  367.     }
  368.  
  369.     /* Set up the color map according to the number of bitplanes */
  370.  
  371.     colormap.Count = 1 << parm.page.depth;
  372.     if (parm.page.depth == 1)
  373.         colormap.ColorTable = (APTR) bcolors;
  374.     else
  375.         colormap.ColorTable = (APTR) ccolors;
  376.  
  377.     parm.page.ybase = 0;
  378.     parm.page.yheight = parm.page.ysize;
  379.     if (ssize != 0 && ssize < parm.page.ysize) parm.page.ysize = ssize;
  380.     if (parm.page.xsize == 0 || parm.page.ysize == 0)
  381.     {   errmsg("page size not set in preferences");
  382.         goto errorexit;
  383.     }
  384.     parm.page.xbytes = (parm.page.xsize + 15) >> 3 & 0xfffffffe;
  385.     parm.page.len = parm.page.xbytes * parm.page.ysize;
  386.  
  387.     /* Allocate the page buffer */
  388.  
  389.     for (i = 0; i < parm.page.depth; i++)
  390.     {   if ((parm.page.buf[i] =
  391.                 AllocMem(parm.page.len, MEMF_PUBLIC|MEMF_CLEAR)) == NULL)
  392.         {   errmsg("can't get page buffer");
  393.             goto errorexit;
  394.         }
  395.     }
  396.  
  397.     /* Initialise the bitmap */
  398.  
  399.     bitmap.BytesPerRow = parm.page.xbytes;
  400.     bitmap.Rows = parm.page.ysize;
  401.     bitmap.Flags = 0;
  402.     bitmap.Depth = parm.page.depth;
  403.     memcpy((char *) bitmap.Planes, (char *) parm.page.buf,
  404.            sizeof bitmap.Planes);
  405.  
  406.     /* Open the print file and check the header */
  407.  
  408.     printfile = fopen(argprint, "r");
  409.     if (printfile == NULL)
  410.     {   errmsg("can't open print file\n");
  411.         goto errorexit;
  412.     }
  413.     s = "%!PS-Adobe-";
  414.     while (*s)
  415.     {   ch = fgetc(printfile);
  416.         if (ch != *s++) goto pferror;
  417.     }
  418.     for (;;)
  419.     {   ch = fgetc(printfile);
  420.         if (ch == '\n') break;
  421.         if (ch == EOF) goto pferror;
  422.     }
  423.     prologue = 1;
  424.     trailer = 0;
  425.  
  426.     /* Initialise for interpretation */
  427.  
  428.     insertbreak();
  429.     SetExcept(~0, SIGBREAKF_CTRL_C);
  430.     breakset = 1;
  431.     insertftrap();
  432.     ftrapset = 1;
  433.  
  434.     parm.copyfunc = (APTR) copypage;
  435.  
  436.     parm.infh = Input();
  437.     parm.outfh = Output();
  438.     parm.errfh = errfh;
  439.  
  440.     arec = PScreateact(&parm);
  441.     if (arec == 0)
  442.     {   errmsg("can't get memory");
  443.         goto errorexit;
  444.     }
  445.     if ((unsigned) arec <= errmax)
  446.     {   arec = 0;
  447.         retcode = 10;
  448.         goto tidyexit;
  449.     }
  450.  
  451.     /* Interpret the argument files */
  452.  
  453.     for (i = 0; i < argfilec; i++)
  454.         if (PSintstring(arec, argfilev[i],
  455.                         -1, PSFLAGFILE|PSFLAGCLEAR|PSFLAGERASE) != 0)
  456.         {   retcode = 10;
  457.             goto tidyexit;
  458.         }
  459.  
  460.     /* Interpret the prologue and each page */
  461.  
  462.     for (;;)
  463.     {   if (trailer) break;
  464.         splitpage();
  465.         if (retcode != 0) break;
  466.         ybase = 0;
  467.         if (PSintstring(arec,
  468.                         prologue ?
  469.             "(t:postband.ps) run" :
  470.             "currentband 1 sub{setband (t:postband.ps) run} for 0 setband",
  471.                         -1, PSFLAGSTRING) != 0)
  472.         {   retcode = 10;
  473.             break;
  474.         }
  475.         prologue = 0;
  476.     }
  477.  
  478.     goto tidyexit;
  479.  
  480.     /* File format error */
  481.  
  482. pferror:
  483.     errmsg("print file not PostScript conforming");
  484.     goto errorexit;
  485.  
  486.     /* Argument errors and usage query */
  487.  
  488. badargs:
  489.     errmsg("arguments bad, or value missing");
  490.     goto badusage;
  491.  
  492. badvalue:
  493.     errmsg("argument bad value");
  494.  
  495. badusage:
  496.     retcode = 20;
  497.  
  498. usage:
  499.     errmsg("usage:\n"
  500.     "    postband [files...] PRINT file [SIZE xyod..s..p.bc.] [MEM fhlv..]");
  501.     goto tidyexit;
  502.  
  503.     /* Tidy up and exit */
  504.  
  505. errorexit:
  506.     retcode = 20;
  507.  
  508. tidyexit:
  509.     DeleteFile("t:postband.ps");
  510.     if (printfile) fclose(printfile);
  511.  
  512.     if (breakset)
  513.     {   SetExcept(0, SIGBREAKF_CTRL_C);
  514.         deletebreak();
  515.         breakset = 0;
  516.     }
  517.     if (ftrapset)
  518.     {   deleteftrap();
  519.         ftrapset = 0;
  520.     }
  521.  
  522.     if (arec) PSdeleteact(arec);
  523.  
  524.     for (i = 0; i < parm.page.depth; i++)
  525.         if (parm.page.buf[i])
  526.         {   FreeMem(parm.page.buf[i], parm.page.len);
  527.             parm.page.buf[i] = NULL;
  528.         }
  529.  
  530.     if (propen) CloseDevice((struct IORequest *) &prreq);
  531.     if (prport) DeletePort(prport);
  532.  
  533.     if (PSbase)  CloseLibrary(PSbase);
  534. }
  535.  
  536. /* Print a string to a DOS file handle */
  537.  
  538. void prints(BPTR fh, char *string)
  539. {   Write(fh, string, strlen(string));
  540. }
  541.  
  542. /* Display an error message */
  543.  
  544. void errmsg(char *string)
  545. {   prints(errfh, "postband: ");
  546.     prints(errfh, string);
  547.     prints(errfh, "\n");
  548. }
  549.  
  550. /* Open the printer device and set up the page size */
  551.  
  552. void setprinter(void)
  553. {   if (propen == 0)
  554.     {   if (OpenDevice("printer.device", 0,
  555.                        (struct IOReqest *) &prreq, 0) != 0)
  556.             return;
  557.         propen = 1;
  558.     }
  559.     if (prport == NULL)
  560.     {   prport = CreatePort(NULL, 0);
  561.         if (prport == NULL) return;
  562.         prreq.io_Message.mn_ReplyPort = prport;
  563.         prsig = 1 << prport->mp_SigBit;
  564.         prdata = (struct PrinterData *) prreq.io_Device;
  565.         prextdata = &prdata->pd_SegmentData->ps_PED;
  566.         prprefs = &prdata->pd_Preferences;
  567.         prden = prprefs->PrintDensity;
  568.     }
  569.     if ((prprefs->PrintShade & SHADE_COLOR) == 0) parm.page.depth = 1;
  570.     setprintden();
  571. }
  572.  
  573. /* Set the printer density */
  574.  
  575. void setprintden(void)
  576. {   int pxsize, pysize;
  577.  
  578.     /* New density, call the device driver to change its extended data.  No
  579.      * error check */
  580.  
  581.     if (prden > 7) prden = 7;
  582.     if (prden != prprefs->PrintDensity)
  583.     {   prreq.io_Command = PRD_DUMPRPORT;
  584.         prrast.BitMap = &bitmap;
  585.         prreq.io_RastPort = &prrast;
  586.         prreq.io_ColorMap = (struct ColorMap *) &colormap;
  587.         prreq.io_Modes = 0;
  588.         prreq.io_SrcX = 0;
  589.         prreq.io_SrcY = 0;
  590.         prreq.io_SrcWidth = 1;
  591.         prreq.io_SrcHeight = 1;
  592.         prreq.io_DestCols = 1;
  593.         prreq.io_DestRows = 1;
  594.         prreq.io_Special = (SPECIAL_DENSITY1 * prden) | SPECIAL_NOPRINT;
  595.         prprefs->PrintDensity = prden;
  596.         DoIO((struct IORequest *) &prreq);
  597.     }
  598.  
  599.     /* Extract the page size and density from the printer device preferences
  600.      * and extended data */
  601.  
  602.     parm.page.xden = prextdata->ped_XDotsInch;
  603.     parm.page.yden = prextdata->ped_YDotsInch;
  604.     if      (prprefs->PrintFlags & PIXEL_DIMENSIONS)
  605.     {   pxsize = prprefs->PrintMaxWidth;
  606.         pysize = prprefs->PrintMaxHeight;
  607.     }
  608.     else if (prprefs->PrintFlags &
  609.                 (BOUNDED_DIMENSIONS|ABSOLUTE_DIMENSIONS))
  610.     {   pxsize = prprefs->PrintMaxWidth * parm.page.xden / 10;
  611.         pysize = prprefs->PrintMaxHeight * parm.page.yden / 10;
  612.     }
  613.     if (pxsize != 0) parm.page.xsize = pxsize;
  614.     if (pysize != 0) parm.page.ysize = pysize;
  615. }
  616.  
  617. /* String to integer conversion; digits only, with error check */
  618.  
  619. int strtoint(char **sp, int *ip)
  620. {   char *s = *sp;
  621.     int i = 0;
  622.     int ch;
  623.     for (;;)
  624.     {   ch = *s;
  625.         if (ch < '0' || ch > '9') break;
  626.         i = i * 10 + (ch - '0');
  627.         s++;
  628.     }
  629.     if (s == *sp)
  630.         return 0;
  631.     else
  632.     {   *sp = s;
  633.         *ip = i;
  634.         return 1;
  635.     }
  636. }
  637.  
  638. /* Signal an interrupt */
  639.  
  640. void __saveds sigint()
  641. {   PSsignalint(arec, 1);
  642. }
  643.  
  644. /* Signal a floating point error */
  645.  
  646. void __saveds sigfpe()
  647. {   PSsignalfpe(arec);
  648. }
  649.  
  650. /* Copy the page to the output */
  651.  
  652. void __saveds __asm copypage(register __d0 int num)
  653. {   ioerror = 0;
  654.     printpage();
  655.     if (ioerror) PSerror(arec, ioerror);
  656. }
  657.  
  658. /* Print the page */
  659.  
  660. void printpage()
  661. {   ULONG sig;
  662.     UWORD prflags;
  663.  
  664.     /* Disable break exceptions so we can wait on the signal instead */
  665.  
  666.     SetExcept(0, SIGBREAKF_CTRL_C);
  667.     breakset = 0;
  668.  
  669.     /* First check the printer is ready */
  670.  
  671.     prreq.io_Command = PRD_QUERY;
  672.     ((struct IOStdReq *) &prreq)->io_Data = (APTR) prstatus;
  673.     if (DoIO((struct IORequest *) &prreq))
  674.     {   ioerror = errioerror;
  675.         return;
  676.     }
  677.     if (((struct IOStdReq *) &prreq)->io_Actual == 1 && prstatus[0] & 3 != 0)
  678.         errmsg("printer not ready (CTRL/C to abort)");
  679.  
  680.     /* Now dump the page */
  681.  
  682.     prrast.BitMap = &bitmap;
  683.     prreq.io_Command = PRD_DUMPRPORT;
  684.     prreq.io_RastPort = &prrast;
  685.     prreq.io_ColorMap = (struct ColorMap *) &colormap;
  686.     prreq.io_Modes = 0;
  687.     prreq.io_SrcX = 0;
  688.     prreq.io_SrcY = 0;
  689.     prreq.io_SrcWidth = parm.page.xsize;
  690.     prreq.io_SrcHeight = parm.page.ysize;
  691.     prreq.io_DestCols = parm.page.xsize;
  692.     prreq.io_DestRows = parm.page.ysize;
  693.     prreq.io_Special = (SPECIAL_DENSITY1 * prden) | SPECIAL_TRUSTME;
  694.     if (ybase + parm.page.ysize >= parm.page.yheight)
  695.         prreq.io_SrcHeight = prreq.io_DestRows =
  696.                 parm.page.yheight - ybase;
  697.     else
  698.         prreq.io_Special |= SPECIAL_NOFORMFEED;
  699.     ybase += prreq.io_SrcHeight;
  700.     prflags = prprefs->PrintFlags;
  701.     prprefs->PrintFlags = prflags & ~DIMENSIONS_MASK | IGNORE_DIMENSIONS;
  702.     prprefs->PrintAspect = ASPECT_HORIZ;
  703.  
  704.     /* We use asynchronous IO so we can abort it with a CTRL/C */
  705.  
  706.     SendIO((struct IORequest *) &prreq);
  707.  
  708.     for (;;)
  709.     {   sig = Wait(prsig | SIGBREAKF_CTRL_C);
  710.         if (sig & SIGBREAKF_CTRL_C)
  711.         {   AbortIO((struct IORequest *) &prreq);
  712.             WaitIO((struct IORequest *) &prreq);
  713.             ioerror = errioerror;
  714.             break;
  715.         }
  716.         if (GetMsg(prport))
  717.             break;
  718.     }
  719.     if (prreq.io_Error != 0) ioerror = errioerror;
  720.  
  721.     /* Restore break exceptions */
  722.  
  723.     SetExcept(~0, SIGBREAKF_CTRL_C);
  724.     breakset = 1;
  725.  
  726.     prprefs->PrintFlags = prflags;
  727. }
  728.  
  729. /* Split the prologue or next page of the print file into the temp file */
  730.  
  731. void splitpage(void)
  732. {   FILE *tempfile;
  733.     char *s;
  734.     int matched, ch;
  735.  
  736.     tempfile = fopen("t:postband.ps", "w");
  737.     if (tempfile == NULL)
  738.     {   errmsg("can't open temporary file");
  739.         retcode = 20;
  740.         return;
  741.     }
  742.  
  743.     matched = 0;
  744.     for (;;)
  745.     {   ch = fgetc(printfile);
  746.  
  747.         /* Comment lines are not copied */
  748.  
  749.         if (ch == '%')
  750.         {   ch = fgetc(printfile);
  751.  
  752.             /* %% Comments may be a trailer */
  753.  
  754.             if (ch == '%')
  755.             {   ch = fgetc(printfile);
  756.                 if      (ch == 'P')
  757.                 {   s = "age:";
  758.                     while (*s)
  759.                     {   ch = fgetc(printfile);
  760.                         if (ch != *s++) goto nomatch;
  761.                     }
  762.                     matched = 1;
  763.                 }
  764.                 else if (ch == 'T')
  765.                 {   s = "railer";
  766.                     while (*s)
  767.                     {   ch = fgetc(printfile);
  768.                         if (ch != *s++) goto nomatch;
  769.                     }
  770.                     if (prologue) goto pferror;
  771.                     matched = 1;
  772.                     trailer = 1;
  773.                 }
  774.             }
  775.  
  776.             /* Skip the rest of the comment */
  777.  
  778. nomatch:    if (ch == EOF) goto pferror;
  779.             for (;;)
  780.             {   ch = fgetc(printfile);
  781.                 if (ch == '\n') break;
  782.                 if (ch == EOF) goto pferror;
  783.             }
  784.         }
  785.  
  786.         /* All other lines are copied to the temp file */
  787.  
  788.         else
  789.         {   for (;;)
  790.             {   if (ch == EOF) goto pferror;
  791.                 if (fputc(ch, tempfile) == EOF) goto tferror;
  792.                 if (ch == '\n') break;
  793.                 ch = fgetc(printfile);
  794.             }
  795.         }
  796.         if (matched) break;
  797.     }
  798.     if (fclose(tempfile) == EOF) goto tferror;
  799.     return;
  800.  
  801. pferror:
  802.     errmsg("print file not conforming or io error");
  803.     goto errorexit;
  804.  
  805. tferror:
  806.     errmsg("error with temporary file");
  807.  
  808. errorexit:
  809.     fclose(tempfile);
  810.     retcode = 20;
  811. }
  812.  
  813. /* End of file "postband.c" */
  814.